package com.lcn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lcn.api.feign.FileServiceFeign;
import com.lcn.base.BaseInfoProperties;
import com.lcn.enums.Sex;
import com.lcn.exceptions.GraceException;
import com.lcn.grace.result.GraceJSONResult;
import com.lcn.grace.result.ResponseStatusEnum;
import com.lcn.mapper.UsersMapper;
import com.lcn.pojo.Users;
import com.lcn.pojo.bo.UserRegisterBO;
import com.lcn.pojo.vo.UsersVO;
import com.lcn.service.UsersService;
import com.lcn.utils.LocalDateUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.UUID;


@Service
@Slf4j
public class UsersServiceImpl extends BaseInfoProperties implements UsersService {

    @Resource
    private UsersMapper usersMapper;

    @Resource
    private FileServiceFeign fileServiceFeign;

    private final String FACE = "http://127.0.0.1:9000/localjava/test.jpg";

    /**
     * 用户注册，注册成功返回用户信息
     * @param userRegisterBO
     * @return
     */
    @Override
    public Users regist(UserRegisterBO userRegisterBO) {
        String mobile = userRegisterBO.getMobile();
        String code = userRegisterBO.getSmsCode();
        String nickname = userRegisterBO.getNickname();
        // 校验验证码
        String cacheCode = redis.get(MOBILE_SMSCODE + mobile);
        if (StringUtils.isBlank(cacheCode) || !cacheCode.equalsIgnoreCase(code)) {
            GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        // 查询用户是否存在
        Users users = queryMobileIfExist(mobile);
        // 用户不存在则创建
        if (users == null) {
            users = createUser(mobile, nickname);
        } else {
            // 该用户已存在，不可重复注册
            GraceException.display(ResponseStatusEnum.USER_ALREADY_EXIST_ERROR);
        }
        // 删除验证码
        redis.del(MOBILE_SMSCODE + mobile);
        return users;
    }

    /**
     * 用户登录，登录成功返回用户信息
     * @param userRegisterBO
     * @return
     */
    @Override
    public UsersVO login(UserRegisterBO userRegisterBO) {
        String mobile = userRegisterBO.getMobile();
        String code = userRegisterBO.getSmsCode();
        // 校验验证码
        String cacheCode = redis.get(MOBILE_SMSCODE + mobile);
        if (StringUtils.isBlank(cacheCode) || !cacheCode.equalsIgnoreCase(code)) {
            GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        // 查询用户是否存在
        Users users = queryMobileIfExist(mobile);
        if (users == null) {
            GraceException.display(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }
        // 删除验证码
        redis.del(MOBILE_SMSCODE + mobile);
        // 分布式session
        String userToken = TOKEN_USER_PREFIX + SYMBOL_DOT + UUID.randomUUID();
        // 单设备登陆
//        redis.set(REDIS_USER_TOKEN + ":" + users.getId(), userToken);
        // 多设备登录
        redis.set(REDIS_USER_TOKEN + ":" + userToken, users.getId());

        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(users, usersVO);
        usersVO.setUserToken(userToken);

        return usersVO;
    }

    /**
     * 登录+注册
     *
     * @param userRegisterBO
     */
    @Override
    public UsersVO registOrLogin(UserRegisterBO userRegisterBO) {
        String mobile = userRegisterBO.getMobile();
        String nickname = userRegisterBO.getNickname();
        String code = userRegisterBO.getSmsCode();
        // 校验验证码
        String cacheCode = redis.get(MOBILE_SMSCODE + mobile);
        if (StringUtils.isBlank(cacheCode) || !cacheCode.equalsIgnoreCase(code)) {
            GraceException.display(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        // 查询用户是否存在
        Users users = queryMobileIfExist(mobile);
        // 不存在就注册
        if (users == null) {
            users = createUser(mobile, nickname);
        }
        // 删除验证码
        redis.del(MOBILE_SMSCODE + mobile);
        // 分布式session
        String userToken = TOKEN_USER_PREFIX + SYMBOL_DOT + UUID.randomUUID();
        // 单设备登陆
//        redis.set(REDIS_USER_TOKEN + ":" + users.getId(), userToken);
        // 多端登录
        redis.set(REDIS_USER_TOKEN + ":" + userToken, users.getId());

        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(users, usersVO);
        usersVO.setUserToken(userToken);

        return usersVO;
    }

    /**
     * 根据手机号查询用户是否存在，如果不存在返回null
     * @param mobile
     * @return
     */
    @Override
    public Users queryMobileIfExist(String mobile) {
        return usersMapper.selectOne(
                new QueryWrapper<Users>()
                        .eq("mobile", mobile)
        );
    }

    /**
     * 创建用户
     * @param mobile
     * @return
     */
    @Override
    public Users createUser(String mobile, String nickname) {
        Users user = new Users();
        // 随机的微信号
        String[] uuid = UUID.randomUUID().toString().split("-");
        String wechatNum = "wx" + uuid[0] + uuid[1];
        nickname = StringUtils.isBlank(nickname) ? wechatNum : nickname;
        user.setWechatNum(wechatNum);
        user.setNickname(nickname);
        user.setRealName("");
        user.setMobile(mobile);
        user.setSex(Sex.secret.type);
        user.setFace(FACE);
        user.setChatBg(FACE);
        user.setFriendCircleBg(FACE);
        user.setWechatNumImg(getQrCode(wechatNum, TEMP_STRING));
        user.setEmail("");
        user.setBirthday(LocalDateUtils.parseLocalDate("1980-01-01", LocalDateUtils.DATE_PATTERN));
        user.setCountry("中国大陆");
        user.setProvince("");
        user.setCity("");
        user.setDistrict("");
        user.setSignature("");
        user.setCreatedTime(LocalDateTime.now());
        user.setUpdatedTime(LocalDateTime.now());
        usersMapper.insert(user);
        return user;
    }

    /**
     * 上传二维码并返回图片地址
     */
    private String getQrCode(String wechatNum, String userId) {
        try {
            String code = fileServiceFeign.generateQrCode(wechatNum, userId);
            return code;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
